/**
 * <男人八题>
 * f[j] = f[j-v]+w,f[j-2*v]+2*w,...,f[j-k*v]+k*w
 * f[j+v]=f[j]+w,f[j-v]*2*w
*/

#include <iostream>
#include <cstring>

using namespace std;

const int N = 20010;

int dp[N], pre[N], q[N];
int n, m;

int main() {
    cin >> n >> m;
    for (int i = 0; i < n; ++i) 
    {
        memcpy(pre, dp, sizeof(dp)); // 复制上一层结果
        int v, w, s;
        cin >> v >> w >> s;
        for (int j = 0; j < v; ++j) // 枚举余数
        {
            int head = 0, tail = -1; //tail 代表队尾,head 代表队头(最前面的元素)
            for (int k = j; k <= m; k += v) 
            {
                if (head <= tail && k - s*v > q[head]) //判断是否超出了s件物品;
                    ++head;
                /*
                如果队头掉出了区间，那么我们就删除队头
                队头是当前区间内的最值，状态转移不用说，主要是要搞明白为什么价值是(k-q[head])/v*w)
                k是当前状态的体积，q[head]表示队列内最值的下标，那么他们的差除以v就是取了几份物品
                */
                while (head <= tail && pre[q[tail]] - (q[tail] - j)/v * w <= pre[k] - (k - j)/v * w)
                    --tail; 
                    /* 剔除不会被用到的元素 若队尾元素小于当前元素，则队尾元素出队；
                    若队内一个元素比当前元素小，则该元素一定不会被用到（单调队列思想）
                    */
                if (head <= tail) // 用最大数更新
                    dp[k] = max(dp[k], pre[q[head]] + (k - q[head])/v * w);
                q[++tail] = k; //去除了比当前小的元素，保证队列里的元素都比当前元素大，入队
            }
        }
    }
    cout << dp[m] << endl;
    return 0;
}
